package com.tanhua.server.service;

import com.tanhua.autoconfig.template.OssTemplate;
import com.tanhua.commons.utils.Constants;
import com.tanhua.dubbo.api.SoundApi;
import com.tanhua.dubbo.api.UserInfoApi;
import com.tanhua.model.domain.UserInfo;
import com.tanhua.model.mongo.Sound;
import com.tanhua.model.vo.ErrorResult;
import com.tanhua.model.vo.SoundVo;
import com.tanhua.server.exception.BusinessException;
import com.tanhua.server.interceptor.UserHolder;
import org.apache.commons.lang3.StringUtils;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.util.concurrent.TimeUnit;

@Service
public class PeachBlossomService {

    @DubboReference
    private SoundApi soundApi;

    @DubboReference
    private UserInfoApi userInfoApi;

    @Autowired
    private OssTemplate ossTemplate;

    @Autowired
    private RedisTemplate<String, String> redisTemplate;

    /**
     * 发送语音
     * @param soundFile
     */
    public void sendSound(MultipartFile soundFile) throws IOException {
        Long userId = UserHolder.getUserId();
        //从redis获取今日发语音的次数
        String key = Constants.SOUND_SAVE_USER_KEY + userId;
        String value = redisTemplate.opsForValue().get(key);
        if (StringUtils.isEmpty(value)) {
            //如果redis为空,设置 key= userId value=10 一天过期
            redisTemplate.opsForValue().set(key, "10", 1, TimeUnit.DAYS);
            value = "10";
        }
        //判断value值是否为小于等于0
        Integer soundTime = Integer.valueOf(value);
        if (soundTime <= 0) {
            //如果value值小于等于0，表示次数已经用尽
            throw new BusinessException(ErrorResult.sendSound());
        }
        try {
            //根据 userId 查询 userinfo
            UserInfo userInfo = userInfoApi.findById(userId);
            //调用 oss 上传文件获取 soundUrl
            String soundUrl = ossTemplate.upload(soundFile.getOriginalFilename(), soundFile.getInputStream());
            //构造sound 存到 MongoDB
            Sound sound = new Sound();
            sound.setSoundUrl(soundUrl);
            sound.setGender(userInfo.getGender());
            sound.setUserId(userId);
            sound.setAge(userInfo.getAge());
            sound.setCreated(System.currentTimeMillis());
            soundApi.saveSound(sound);
            //最后对redis中的value值减一
            soundTime -= 1;
            redisTemplate.opsForValue().set(key, soundTime.toString(), 1, TimeUnit.DAYS);
        } catch (IOException e) {
            throw new RuntimeException("发送语音失败");
        }
    }

    /**
     * 接收语音
     * @return
     */
    public SoundVo getSound() {
        Long userId = UserHolder.getUserId();
        //从redis获取今日获取语音的次数
        String key = Constants.SOUND_GET_USER_KEY + userId;
        String value = redisTemplate.opsForValue().get(key);
        if (StringUtils.isEmpty(value)) {
            //如果redis为空,设置 key= userId value=10 一天过期
            redisTemplate.opsForValue().set(key, "10", 1, TimeUnit.DAYS);
            value = "10";
        }
        Integer soundTime = Integer.valueOf(value);
        //判断value值是否为小于等于0
        if (soundTime <= 0) {
            //如果value值小于等于0，表示次数已经用尽
            throw new BusinessException(ErrorResult.getSound());
        }
        //根据 当前用户的 userId 查询 userinfo
        UserInfo userInfo = userInfoApi.findById(userId);
        //根据 userId 查询 sound表 的 获取一个推荐的 sound
        Sound sound = soundApi.getSoundByRecommend(userId);
        //根据 sound 的 sid 修改 sound的 state
        if (sound == null) {
            throw new BusinessException(ErrorResult.noSound());
        }
        sound.setState("1");
        soundApi.updateById(sound);
        //构造vo返回
        UserInfo info = userInfoApi.findById(sound.getUserId());
        SoundVo vo = SoundVo.init(info, sound);
        //对redis中的value值减一
        soundTime -= 1;
        redisTemplate.opsForValue().set(key, soundTime.toString());
        vo.setRemainingTimes(soundTime);
        return vo;
    }
}
